#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_SHT4x.h>
#include <ESP8266WiFi.h>
#include <WiFiManager.h>
#include <PubSubClient.h>
#include <FS.h>
#include <ArduinoJson.h>

#define RELAY_PIN 12
#define LOOP_INTERVAL 5000  // 5秒读取一次温湿度

Adafruit_SHT4x *sht4 = nullptr;  // 动态对象
WiFiClient espClient;
PubSubClient client(espClient);

String mqtt_server;
String mqtt_user;
String mqtt_pass;

String topic_temp = "home/esp12s/temperature";
String topic_hum  = "home/esp12s/humidity";
String topic_relay_state = "home/esp12s/relay/state";
String topic_relay_set   = "home/esp12s/relay/set";

bool relay_state = false;
unsigned long lastRead = 0;

// ================== SPIFFS 保存/读取 ==================
void saveConfig() {
  DynamicJsonDocument doc(512);
  doc["mqtt_server"] = mqtt_server;
  doc["mqtt_user"]   = mqtt_user;
  doc["mqtt_pass"]   = mqtt_pass;
  File f = SPIFFS.open("/config.json", "w");
  if(f){ serializeJson(doc, f); f.close(); }
}

void loadConfig() {
  if(!SPIFFS.begin()) return;
  if(SPIFFS.exists("/config.json")){
    File f = SPIFFS.open("/config.json","r");
    if(f){
      DynamicJsonDocument doc(512);
      deserializeJson(doc,f);
      mqtt_server = doc["mqtt_server"].as<String>();
      mqtt_user   = doc["mqtt_user"].as<String>();
      mqtt_pass   = doc["mqtt_pass"].as<String>();
      f.close();
    }
  }
}

// ================== 继电器 ==================
void setRelay(bool on){
  relay_state = on;
  digitalWrite(RELAY_PIN, relay_state?HIGH:LOW);
  client.publish(topic_relay_state.c_str(), relay_state?"ON":"OFF", true);
}

// ================== MQTT ==================
void mqttCallback(char* topic, byte* payload, unsigned int length){
  String msg;
  for(unsigned int i=0;i<length;i++) msg += (char)payload[i];
  if(String(topic) == topic_relay_set){
    if(msg=="ON") setRelay(true);
    else if(msg=="OFF") setRelay(false);
  }
}

void connectMQTT(){
  while(!client.connected()){
    if(client.connect("ESP12SClient", mqtt_user.c_str(), mqtt_pass.c_str())){
      client.subscribe(topic_relay_set.c_str());
    } else delay(5000);
  }
}

// ================== Setup ==================
void setup(){
  Serial.begin(115200);

  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);

  Wire.begin(4,5);  // SDA=GPIO4, SCL=GPIO5
  sht4 = new Adafruit_SHT4x();
  sht4->begin(&Wire);  // 不阻塞，即使失败也继续

  loadConfig();

  WiFiManager wm;
  WiFiManagerParameter pm_server("server","MQTT Server",mqtt_server.c_str(),40);
  WiFiManagerParameter pm_user("user","MQTT User",mqtt_user.c_str(),32);
  WiFiManagerParameter pm_pass("pass","MQTT Pass",mqtt_pass.c_str(),32);
  wm.addParameter(&pm_server); wm.addParameter(&pm_user); wm.addParameter(&pm_pass);

  if(!wm.autoConnect("ESP12S-AP")) ESP.restart();

  mqtt_server = pm_server.getValue();
  mqtt_user = pm_user.getValue();
  mqtt_pass = pm_pass.getValue();
  saveConfig();

  client.setServer(mqtt_server.c_str(),1883);
  client.setCallback(mqttCallback);
  connectMQTT();
}

// ================== Loop ==================
void loop(){
  client.loop();

  unsigned long now = millis();
  if(now - lastRead >= LOOP_INTERVAL){
    lastRead = now;
    float t=0,h=0;
    if(sht4 && sht4->begin(&Wire)){
      sensors_event_t humidity,temp;
      sht4->getEvent(&humidity,&temp);
      t = temp.temperature;
      h = humidity.relative_humidity;
    }

    // 发布温湿度
    client.publish(topic_temp.c_str(), String(t).c_str(), true);
    client.publish(topic_hum.c_str(), String(h).c_str(), true);
  }
}
